<script setup lang="ts">
import {onBeforeMount, ref, watch} from "vue";
import {loginConfigStore} from "@/store/user/loginConfigStore";
import {useAppConfigStore} from "@/store/system/appConfigStore";
import {getWebConfig} from "@/api/system/system";
import {ECode, setMetaInfo} from "@/util/commonUtil";
import _ from "lodash";
import {message} from "ant-design-vue";
import {
  QqOutlined,
  GoogleOutlined,
  WechatOutlined,
  GithubOutlined,
  RedoOutlined
} from '@ant-design/icons-vue'
import {delCookie, getCookie, setCookie, setTokenCookie} from "@/util/cookieUtil";
import {useRoute} from "vue-router";
import {getLoginKeyByWechat, getWeChatLoginUrl, loginCheck} from "@/api/wechat/wechat";
import {authVerify, loginByPassword, loginByThirdParty} from "@/api/user/user";
import RegisterBox from '@/components/registerBox/index.vue'
import {userConfigStore} from "@/store/user/userConfigStore";
import {cookieToken} from "@/config/CookieConfig";

const props = defineProps({
  show: {
    type: Boolean,
    required: true
  }
});
// 登录类别
const loginType = ref({
  password: true,
  gitee: true,
  github: true,
  qq: true,
  wechat: true,
  personWechat: true
})

const loginTypeData = ref<any>([])
const loginPriorityData = ref<any>('')
const showPasswordLogin = ref<boolean>(true)
// 微信公众号登录显示
const showPersonWechatLogin = ref<boolean>(false)
const wechatOrCode = ref('')
const webConfig = ref<any>({})
const wechatLoginKey = ref<any>({})
const timeInterval = ref<any>(null)
const loginForm = ref({
  userName: '',
  password: '',
  isRememberMe: false
})
const refresh = ref<boolean>(false)
// 微信请求标志
const flagCount = ref<number>(0)

const showLogin = ref<boolean>(props.show)
const registerShow = ref<boolean>(false)

const route = useRoute()

watch(() => loginConfigStore().loginMessage, () => {
  showLogin.value = true;
})

onBeforeMount(async () => {
  await getWebConfig().then((res: any) => {
    if (res.code === ECode.SUCCESS) {
      webConfig.value = res.data
      loginTypeData.value = res.data.loginTypeList
      loginPriorityData.value = res.data.loginPriority
      useAppConfigStore().setAppConfig(res.data)
      setMetaInfo(res.data.title, res.data.keyword, res.data.summary, res.data.logoPhoto)
    } else {
      message.error('获取系统配置失败！')
    }
  })
  // 设置登录类型
  setLoginTypeList()
})

/*============================================================*/
function setLoginTypeList() {
  if (!_.isUndefined(loginTypeData.value)) {
    let loginTypeList = JSON.parse(loginTypeData.value)
    for (let a = 0; a < loginTypeList.length; a++) {
      switch (loginTypeList[a]) {
        case '1': {
          loginType.value.password = false
        }
          break
        case '2': {
          loginType.value.gitee = false
        }
          break
        case '3': {
          loginType.value.github = false
        }
          break
        case '4': {
          loginType.value.qq = false
        }
          break
        case '5': {
          // 公众号
          loginType.value.wechat = false
        }
          break
        case '7': {
          // 个人微信
          loginType.value.personWechat = false
        }
          break
        default: {
          message.error('登录方式设置有误！')
        }
      }
    }
// 控制一下优先级 1 账号密码 5 微信公众号 7 微信
    let isShow = false
    if (loginPriorityData.value) {
      let loginPriority = loginPriorityData.value
      isShow = true
      if (loginPriority === '1') {
        showPasswordLogin.value = true
        showPersonWechatLogin.value = false
      }
      if (loginPriority === '5') {
        showPasswordLogin.value = false
        showPersonWechatLogin.value = false
      }
      if (loginPriority === '7') {
        showPasswordLogin.value = false
        showPersonWechatLogin.value = true
      }
    }
    if (!isShow) {
      // 只有当开启微信登录，并且未账号密码时，才主动显示扫码页面
      showPasswordLogin.value = !(loginType.value.password && !loginType.value.wechat)
    }

  }
}

function goLoginAuthType(item: string) {
  showPersonWechatLogin.value = false
  // 记录跳转地址，后续登录后做跳转到此页面
  setCookie('redirectUrl', route.path, 1)
  // 判断是否点击公众号登录
  if (item === 'wechat') {
    getWechatLoginKey()
    return
  }
  if (item === 'password') {
    showPersonWechatLogin.value = false
    showPasswordLogin.value = true
    return
  }
  if (item === 'personWechat') {
    showPersonWechatLogin.value = true
    getWeChatLoginUrlMethod()
    return
  }
  let params = new URLSearchParams()
  params.append('source', item)
  params.append('type', 'login')
  loginByThirdParty(params).then((response: any) => {
    if (response.code === ECode.SUCCESS) {
      window.location.href = response.data.url
    }
  })
}

// 获取微信登录key
async function getWechatLoginKey() {
  showPasswordLogin.value = false
  await getLoginKeyByWechat().then((response: any) => {
    if (response.code === ECode.SUCCESS) {
      let loginKey = response.data
      wechatLoginKey.value = loginKey
      let count = 0
      let interval = setInterval(() => {
        count++
        // 当检查15次未扫码的时候，将二维码失效
        if (count > 30) {
          refresh.value = true
          wechatLoginKey.value.loginKey = '验证码失效,请刷新'
          clearInterval(interval)
        }
        let params: any = {}
        params.code = loginKey.loginKey
        params.ticket = loginKey.ticket
        checkLoginByWechat(params)
      }, 3000)
      timeInterval.value = interval
      flagCount.value = 0
      refresh.value = false
    }
  })
}

function checkLoginByWechat(params: any) {
  loginCheck(params).then((response: any) => {
    flagCount.value += 1
    if (response.code === ECode.SUCCESS) {
      // 判断url中是否含有token
      let token = response.data
      if (!_.isUndefined(token)) {
        // 设置token七天过期
        setTokenCookie(cookieToken, token, 7)
        location.reload()
      }
    } else {
      if (response.message === ECode.WECHAT_POLLING && flagCount.value < 2) {
        message.info('等待用户扫码验证')
      }
    }
  })
}

function getWeChatLoginUrlMethod() {
  let params = new URLSearchParams()
  params.append('operateType', 'login')
  getWeChatLoginUrl(params).then((response: any) => {
    if (response.code === ECode.SUCCESS) {
      let data = response.data
      //@ts-ignore
      new WxLogin({
        // 需要显示内嵌二维码的容器id
        id: 'wechatQrCode',
        self_redirect: true,
        // 应用ID
        appid: data.appId,
        // 网页默认即可
        scope: data.scope,
        // 授权成功后回调的url
        redirect_uri: encodeURIComponent(data.redirect_uri),
        // 可设置为简单的随机数加session用来校验
        state: data.state,
        // 二维码的样式，提供"black"、"white"可选。
        style: 'black',
        // 自定义样式链接
        href: 'https://oos.moguit.cn/cdn/wechatLogin.css'
      })
      // 开始定时扫描，判断是否完成登录
      let count = 0
      let interval = setInterval(() => {
        count++
        // 当检查15次未扫码的时候，将二维码失效，重试关闭接口请求
        if (count > 30) {
          wechatLoginKey.value.loginKey = '登录二维码失效,请刷新'
          clearInterval(interval)
        }
        let params: any = {}
        params.code = data.loginKey
        params.ticket = data.ticket
        checkLoginByWechat(params)
      }, 3000)
    }
  })
}

async function refreshWechat() {
  clearInterval(timeInterval.value)
  await getWechatLoginKey()
  message.success('刷新二维码成功')
}

function goBack(e: any) {
  goLoginAuthType(e)
  clearInterval(timeInterval.value)
}

async function login() {
  if (_.isNull(loginForm.value.userName) || _.isEmpty(loginForm.value.userName)) {
    message.warning('请输入用户名！')
    return
  }
  if (_.isNull(loginForm.value.password) || _.isEmpty(loginForm.value.password)) {
    message.warning('请输入密码！')
    return
  }
  setCookie('redirectUrl', route.fullPath, 1)
  let params: any = {}
  params.userName = loginForm.value.userName
  params.passWord = loginForm.value.password
  params.isRememberMe = loginForm.value.isRememberMe
  await loginByPassword(params).then((response: any) => {
    if (response.code === ECode.SUCCESS) {
      // 设置token
      setTokenCookie(cookieToken, response.data.token, 7)
      getTokenByUrl()
      // 跳转到首页
      // window.location.href = ('/' + '?token=' + response.data.token)
      const cookie = getCookie('redirectUrl');
      if (!_.isNull(cookie) || !_.isUndefined(cookie)) {
        window.location.href = (String(cookie))
        message.success('登录成功')
        return
      } else {
        window.location.href = ('/')
        message.success('登录成功')
      }
    } else {
      message.error(response.message)
    }
  })
}

async function getTokenByUrl() {
  let token: any = getCookie(cookieToken);
  if (!_.isNull(token)) {
    await authVerify(token).then((response: any) => {
      if (response.code === ECode.SUCCESS) {
        console.log("LoginBoxAuthVerify===>成功!")
        userConfigStore().setLoginState(true)
        userConfigStore().setUserInfo(response.data)
        userConfigStore().setAuthCode(response.data.authCodeList)
      } else {
        userConfigStore().setLoginState(false)
        delCookie(cookieToken);
      }
    })
  }
}

function clickRegister() {
  showLogin.value = false
  registerShow.value = true
}

function registerCallback(e: boolean) {
  showLogin.value = e
  registerShow.value = false
}
</script>

<template>
  <section class="userAuthContainer">
    <div class="loginBox" v-if="showLogin">
      <a-modal v-model:open="showLogin" :closable="false" :footer="null" centered>
        <template #title>
          <div class="loginTitle">
          <span class="w-full text-2xl flex justify-center items-center">
            <span class="text-rose-400">{{ webConfig.title }}</span>
            <span>社区登录</span>
          </span>
          </div>
        </template>
        <!--账号密码登录-->
        <div class="loginByPassword lg:w-[24rem] m-auto" v-if="showPasswordLogin && !showPersonWechatLogin">
          <a-form :model="loginForm" autocomplete="off">
            <!-- 用户名 -->
            <a-form-item name="userName" :rules="[{ required: true, message: '请输入用户名!' }]">
              <div class="flex-column mb-2">
                <label class="font-semibold">邮箱</label>
              </div>
              <div class="inputForm flex items-center pl-2.5 rounded-[10px] h-[50px]">
                <svg xmlns="http://www.w3.org/2000/svg" width="20" viewBox="0 0 32 32" height="20">
                  <g data-name="Layer 3" id="Layer_3">
                    <path
                        d="m30.853 13.87a15 15 0 0 0 -29.729 4.082 15.1 15.1 0 0 0 12.876 12.918 15.6 15.6 0 0 0 2.016.13 14.85 14.85 0 0 0 7.715-2.145 1 1 0 1 0 -1.031-1.711 13.007 13.007 0 1 1 5.458-6.529 2.149 2.149 0 0 1 -4.158-.759v-10.856a1 1 0 0 0 -2 0v1.726a8 8 0 1 0 .2 10.325 4.135 4.135 0 0 0 7.83.274 15.2 15.2 0 0 0 .823-7.455zm-14.853 8.13a6 6 0 1 1 6-6 6.006 6.006 0 0 1 -6 6z"></path>
                  </g>
                </svg>
                <input placeholder="请输入用户名" class="input ml-2.5 w-full h-full rounded-[10px]" type="text"
                       v-model="loginForm.userName"
                       :disabled="loginType.password">
              </div>
            </a-form-item>
            <!-- 密码 -->
            <a-form-item name="password" :rules="[{ required: true, message: '请输入密码!' }]">
              <div class="flex-column mb-2">
                <label class="font-semibold">密码</label>
              </div>
              <div class="inputForm flex items-center pl-2.5 rounded-[10px] h-[50px]">
                <svg xmlns="http://www.w3.org/2000/svg" width="20" viewBox="-64 0 512 512" height="20">
                  <path
                      d="m336 512h-288c-26.453125 0-48-21.523438-48-48v-224c0-26.476562 21.546875-48 48-48h288c26.453125 0 48 21.523438 48 48v224c0 26.476562-21.546875 48-48 48zm-288-288c-8.8125 0-16 7.167969-16 16v224c0 8.832031 7.1875 16 16 16h288c8.8125 0 16-7.167969 16-16v-224c0-8.832031-7.1875-16-16-16zm0 0"></path>
                  <path
                      d="m304 224c-8.832031 0-16-7.167969-16-16v-80c0-52.929688-43.070312-96-96-96s-96 43.070312-96 96v80c0 8.832031-7.167969 16-16 16s-16-7.167969-16-16v-80c0-70.59375 57.40625-128 128-128s128 57.40625 128 128v80c0 8.832031-7.167969 16-16 16zm0 0"></path>
                </svg>
                <input placeholder="请输入密码" class="input ml-2.5 w-full h-full rounded-[10px]" type="password"
                       v-model="loginForm.password"
                       :disabled="loginType.password">
              </div>
            </a-form-item>
            <a-form-item>
              <a-form-item name="remember" no-style>
                <a-checkbox v-model:checked="loginForm.isRememberMe">记住我</a-checkbox>
              </a-form-item>
              <a class="float-right" href="javascript:void(0)" @click.prevent="clickRegister">账号注册</a>
            </a-form-item>
            <!-- 登录 -->
            <a-form-item>
              <button
                  type="submit"
                  class="loginSubmit flex justify-center items-center text-[15px] font-medium rounded-[10px] h-[50px] w-full cursor-pointer"
                  @click="login">
                登录
              </button>
            </a-form-item>
          </a-form>
          <a-divider>第三方登录</a-divider>
          <!-- 更多登录方式 -->
          <div class="moreLoginType flex justify-center items-center text-2xl gap-4">
            <a-tooltip title="QQ登录" v-if="!loginType.qq">
              <QqOutlined style="color: #38bdf8" @click="goLoginAuthType('qq')"/>
            </a-tooltip>
            <a-tooltip title="Gitee登录" v-if="!loginType.gitee">
              <GoogleOutlined style="color: #e11d48" @click="goLoginAuthType('gitee')"/>
            </a-tooltip>
            <a-tooltip title="Github登录" v-if="!loginType.github">
              <GithubOutlined style="color:#38bdf8;" @click="goLoginAuthType('github')"/>
            </a-tooltip>
            <a-tooltip title="微信公众号登录" v-if="!loginType.wechat">
              <WechatOutlined style="color: #22c55e" @click="goLoginAuthType('wechat')"/>
            </a-tooltip>
            <a-tooltip title="微信登录" v-if="!loginType.personWechat">
              <WechatOutlined style="color: #c084fc" @click="goLoginAuthType('personWechat')"/>
            </a-tooltip>
          </div>
        </div>

        <!--微信登录-->
        <div class="loginByWechat lg:w-[24rem] m-auto" v-if="showPersonWechatLogin">
          <div id="wechatQrCode" class="text-center"></div>
          <a-qrcode class="ml-[25%]" :value="wechatOrCode" type="'canvas'"/>
        </div>

        <!--微信公众号登录-->
        <div class="loginByGZH lg:w-[24rem] m-auto flex flex-col items-center justify-center gap-4"
             v-if="!showPasswordLogin && !showPersonWechatLogin">
          <div class="QrCode h-[200px] w-[200px] mb-2">
            <img class="w-full h-full" :src="webConfig.wechatPhoto" alt="GZH">
          </div>
          <span class="w-full text-[14px] text-center">
          扫码关注公众号，回复<b class="text-orange-500">验证码</b>完成登录
        </span>
          <a-row class="mb-2">
            <span class="text-[14px]" style="color: #303133">登录验证码：</span>
            <span class="font-bold" style="color: red;">{{ wechatLoginKey.loginKey }}</span>
            <RedoOutlined class="ml-2" style="color:#38bdf8;" @click="refreshWechat" v-if="refresh"/>
          </a-row>
          <div class="goBack">
            <a-button type="primary" class="text-[14px] cursor-pointer" @click="goBack('password')">
              返回账号登录
            </a-button>
          </div>
        </div>
      </a-modal>
    </div>
    <RegisterBox :show="registerShow" :webConfig="webConfig" @registerCallback="registerCallback"/>
  </section>
</template>

<style scoped lang="less">
:deep(.ant-divider-inner-text) {
  color: #d4d4d4;
}

.loginTitle:before {
  content: '';
  position: absolute;
  width: 180px;
  height: 176px;
  top: -135px;
  right: 0;
  left: 0;
  margin: 0 auto;
  background: url(@/assets/background/loginHeader.webp) no-repeat center / 100%;
}

::placeholder {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}

.flex-column > label {
  color: #151717;
}

.inputForm {
  border: 1.5px solid #ecedec;
  transition: 0.2s ease-in-out;
}

.inputForm:focus-within {
  border: 1.5px solid #2d79f3;
}

.loginSubmit {
  margin: 20px 0 10px 0;
  background-color: #2d79f3;
  border: none;
  color: white;
}
</style>
